import json
from datetime import datetime
import time
from decimal import Decimal

from django.core.paginator import Paginator
from django.db import transaction
from django import http
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect, reverse
from django.views import View


from django_redis import get_redis_connection

from apps.ausers.models import Address
from apps.goods.models import SKU


from apps.orders.models import OrderInfo, OrderGoods

#1.结算页面
from utils.response_code import RETCODE


class OrderSettlementView(LoginRequiredMixin, View):
    #1.显示结算页面
    def get(self, request):
        #地址
        addresses = Address.objects.filter(user = request.user, is_deleted=False)
        #取数据
        redis_client = get_redis_connection('carts')
        redis_cart = redis_client.hgetall(request.user.id)
        carts_dict = {}
        for data in redis_cart.items():
            sku_id = int(data[0].decode())
            data_dict = json.loads(data[1].decode())
            if data_dict['selected']:
                carts_dict[sku_id] = data_dict

        total_count = 0
        total_amount = Decimal(0.00)
        skus = SKU.objects.filter(id__in = carts_dict.keys())
        for sku in skus:
            sku.count = carts_dict[sku.id].get('count')
            sku.amount = sku.count * sku.price

            total_count += sku.count
            total_amount += sku.amount

        freight = Decimal('10.00')
        # 算总金额
        total_price_all = total_amount + freight
        # 返回格式
        context = {
            'addresses': addresses,
            'skus': skus,
            'total_count': total_count,
            'total_amount': total_amount,
            'freight': freight,
            'payment_amount': total_price_all,
            'default_address_id': request.user.default_address_id
        }


        return render(request, 'place_order.html', context)


#2.提交订单
class OrderCommitView(View):
    def post(self,request):
        #接受数据
        json_dict = json.loads(request.body.decode())
        address_id = json_dict.get('address_id')
        pay_method = json_dict.get('pay_method')
        user = request.user
        #校验 判空 地址  付款方式
        if not all([address_id, pay_method]):
            return http.HttpResponseBadRequest("参数不全")
        try:
            address = Address.objects.get(id = address_id)
        except Exception as e:
            return http.HttpResponseBadRequest("地址不存在")

        if pay_method not in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
            return http.HttpResponseBadRequest("请选择正确的付款方式")

        #order_id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + '%09d' %user.id
        #添加事件
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                #构建OrderInfo数据
                order = OrderInfo.objects.create(
                    order_id = order_id,
                    user = user,
                    address = address,
                    total_count = 0,
                    total_amount = Decimal('0'),
                    freight = Decimal('10.0'),
                    pay_method = pay_method,
                    status = OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY'] else
                    OrderInfo.ORDER_STATUS_ENUM['UNSEND']

                )
                #获取数据库,商品选中
                redis_client = get_redis_connection('carts')
                redis_data = redis_client.hgetall(user.id)
                cart_selected_dict = {}
                for data in redis_data.items():
                    sku_id = int(data[0].decode())
                    sku_dict = json.loads(data[1].decode())
                    if sku_dict['selected']:
                        cart_selected_dict[sku_id] = sku_dict

                sku_ids = cart_selected_dict.keys()
                # skus = SKU.objects.filter(id__in = sku_ids)
                for sku_id in sku_ids:
                    while True:
                        # 销量小于库存
                        sku = SKU.objects.get(id = sku_id)
                        origin_sales = sku.sales
                        origin_stock = sku.stock
                        sku_count = cart_selected_dict[sku.id]['count']
                        if sku.stock < sku_count:
                            transaction.savepoint_rollback(save_id)
                            return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '库存不足'})
                        # sku，spu 销量+  sku 库存-
                        # sku.stock -= sku_count
                        # sku.sales += sku_count
                        # sku.save()
                        time.sleep(7)
                        new_stock = origin_stock - sku_count
                        new_sales = origin_sales + sku_count
                        result = SKU.objects.filter(id = sku.id, stock = origin_stock).update(stock = new_stock, sales = new_sales)
                        if result == 0:
                            continue
                        sku.spu.sales += sku_count
                        sku.spu.save()
                        # 表OrderGooogs数据
                        OrderGoods.objects.create(
                            order = order,
                            sku =sku,
                            count = sku_count,
                            price = sku.price
                        )
                        #  #取total_count, total_amount
                        order.total_count += sku_count
                        order.total_amount += (sku_count*sku.price)
                        break

                order.total_amount += order.freight
                order.save()
                transaction.savepoint_commit(save_id)
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '订单失败'})

        #清空购物车
        redis_client.hdel(user.id, *cart_selected_dict)
        #返回
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '下单成功', 'order_id': order.order_id})


#3.显示提交订单成功页面
class OrderSuccessView(View):
    def get(self, request):
        context = {
            'order_id':request.GET.get('order_id'),
            'payment_amount':request.GET.get('payment_amount'),
            'pay_method ':request.GET.get('pay_method ')
        }
        return render(request, 'order_success.html', context)


class DisplayView(LoginRequiredMixin, View):
    # 订单展示
    def get(self, request, page_num):

        # 根据用户id获取用户的订单
        page_skus = OrderInfo.objects.filter(user_id=request.user.id).order_by('-create_time')
        # 将订单分页
        paginator = Paginator(page_skus, 5)
        # 获取总页数
        total_page = paginator.num_pages
        # 请求页的订单
        page_orders = paginator.page(page_num)

        # 给前端返回数据字典
        page_list = []
        #　对订单页进行遍历得到此页所有订单
        for order in page_orders:
            page_list.append({
                'create_time':  order.create_time,
                'order_id': order.order_id,
                'status': order.status,
                'pay_method': order.pay_method,
                'total_amount': order.total_amount,
                'freight': order.freight,
                # 商品列表
                'skus': order.skus.all()
            })
        context = {
            'page_list': page_list,
            'page_num': page_num,
            'total_page': total_page
        }
        return render(request, 'user_center_order.html', context)


class OrderCommentsView(View):
    def get(self, request):
        # 1. 接收参数
        order_id = request.GET.get('order_id')

        order = OrderInfo.objects.get(order_id=order_id)
        goods = order.skus.all()
        details = []
        for good in goods:
            sku = good.sku
            id = sku.id
            name = sku.name
            price = str(sku.price)
            details.append({
                'sku_id':id,
                'name':name,
                'price':price,
                'order_id':order_id,
                'comment':good.comment,
                'display_score':good.score,
                'default_image_url':sku.default_image.url
            })
            order.details = details


        context = {
            'skus':details
        }
        return render(request, 'goods_judge.html', context)

    # 提交评论
    def post(self, request):
        json_dict = json.loads(request.body.decode())
        order_id = json_dict.get('order_id')
        sku_id=json_dict.get('sku_id')
        comment=json_dict.get('comment')
        score=json_dict.get('score')
        is_anonymous=json_dict.get('is_anonymous')
        if is_anonymous is None:
            is_anonymous = False

        good = OrderGoods.objects.get(order_id=order_id, sku_id=sku_id)
        good.score = score
        good.comment = comment
        good.is_anonymous = is_anonymous
        good.is_commented = True
        good.save()

        orderinfo = good.order
        orderinfo.status = 5
        orderinfo.save()

        sku = good.sku
        sku.comments += 1
        sku.save()

        spu = sku.spu
        spu.comments += 1
        spu.save()

        return http.JsonResponse({'code':RETCODE.OK, 'errmsg':'评论成功'})